/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License Version
 *  3 as published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
 *  USA.
 */

#include "toolbar.h"
#include <QTimeLine>
#include <math.h>

class ToolbarItem{
public:
    ToolbarItem(QAction* a, const QRectF& r, QPixmap* p):action(a), rect(r), pixmap(p){}
    ~ToolbarItem(){
    }

    QAction* action;
    QRectF rect;
    QPixmap* pixmap;
};

class ToolbarPrivate{
public:
    ToolbarPrivate():gap(10),piesize(QSizeF(48, 48)), hidden(false), content(0)
    {
    }
    ~ToolbarPrivate(){};
    QRect rect;
    qreal gap;
    QList<ToolbarItem*> items;
    QSize grid;
    Toolbar::Type type;

    QSizeF piesize;
    QSizeF size;
    bool hidden;
    QGraphicsProxyWidget* content;
};

Toolbar::Toolbar(Type dock) :
        QGraphicsItem(0), O_PRIVATE_CREATE(Toolbar)
{
    O_D(Toolbar);
    d->type = dock;
}

Toolbar::~Toolbar()
{
    O_D(Toolbar);
    foreach(ToolbarItem* i, d->items){
        delete i;
    }

    O_PRIVATE_DELETE;
}

QGraphicsProxyWidget* Toolbar::content()const
{
    O_D(Toolbar);
    return d->content;
}

void Toolbar::setContent(QGraphicsProxyWidget* content)
{
    O_D(Toolbar);
    d->content = content;
    d->content->setPos(d->gap, d->gap);
    d->content->show();
    content->setZValue(101);
    updateSize();
    update();
}

QRectF Toolbar::boundingRect() const
{
    O_D(const Toolbar);
    return QRectF(QPointF(0, 0), d->size);
}

void Toolbar::updateSize()
{
    O_D(Toolbar);

    if (d->content != NULL){
        d->grid = QSize(1, 1);
        d->size = QSizeF(d->gap * 2 + d->content->boundingRect().width(), d->gap * 2 + d->content->boundingRect().height());
        prepareGeometryChange();
    }else{
        if (d->items.isEmpty()){
            d->size = d->piesize;
        }else if (d->items.size() == 1){
            d->grid = QSize(1, 1);
        }else if (d->type == sqare){
            double h = sqrt(d->items.size());
            int hi = qRound(h);
            if (h != (double)(int)h)
                d->grid = QSize(hi + 1, hi);
            else
                d->grid = QSize(hi, hi);
        }else if (d->type == horizontal){
            d->grid = QSize(d->items.size(), 1);
        }else  if (d->type == vertical){
            d->grid = QSize(1, d->items.size());
        }else{
            Q_ASSERT(false);
            d->grid = QSize(1, 1);
        }

        d->size = QSizeF((d->gap * (d->grid.width() + 1)) + (d->piesize.width() * d->grid.width()),
                         (d->gap * (d->grid.height() + 1)) + (d->piesize.height() * d->grid.height()));
    }
    if (d->hidden){
        if (d->type == horizontal)
            d->size = QSizeF(d->size.width(), 5);
        else
            d->size = QSizeF(5, d->size.height());
    }

    prepareGeometryChange();
    //    qDebug() << QString("size:(%1, %21)").arg(d->pixmaps.size()).arg(sqrt(d->pixmaps.size()));
    //    qDebug() << QString("update grid:(%1, %2)").arg(d->grid.width()).arg(d->grid.height());
    //    qDebug() << QString("update size:(%1, %2)").arg(d->size.width()).arg(d->size.height());
}

void Toolbar::setHidden(bool hidden)
{
    O_D(Toolbar);
    d->hidden = hidden;
    if (d->content != NULL)
       d->content->setVisible(!hidden);

    updateSize();
    update();
}

void Toolbar::mousePressEvent(QGraphicsSceneMouseEvent  *event)
{
    O_D(Toolbar);
    foreach(ToolbarItem* item, d->items)
    {
        if (item->rect.contains(event->pos())){
            item->action->trigger();
            qDebug() << "Toolbar item click";
            return;
        }
    }
}

void Toolbar::setInvisible(bool inv)
{
    O_D(Toolbar);
    if (inv){
        setZValue(-1);
    }else{
        setZValue(99);
    }

    if (d->content != NULL){
        d->content->setZValue(inv ? -1 : 100);
    }


}

void Toolbar::append(QAction* action)
{
    O_D(Toolbar);
    d->items.append(new ToolbarItem(action, QRectF(), new QPixmap(action->icon().pixmap(d->piesize.toSize()))));
    updateSize();
    update();
}

void Toolbar::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    O_D(Toolbar);

    QRectF rect = boundingRect();


    QColor col(128, 128, 128, 128);
    painter->setPen(col);
    painter->drawRoundedRect(0, 0, rect.width(), rect.height(), 5, 5);
    painter->fillRect(rect, col);
    if (d->hidden){
        return;
    }

    qreal x = d->gap;
    qreal y = d->gap;


    if (d->content != NULL){
        d->content->setPos(pos().x() + x, pos().y() + y);
    }

    int gx = 0;
    foreach(ToolbarItem* item, d->items){

        item->rect = QRectF(QPointF(x, y), d->piesize);
        if (!item->pixmap->isNull()){
            painter->drawPixmap(QPointF(x, y), *item->pixmap);
        }else{
            painter->drawRoundedRect(item->rect, 4, 4);
            painter->drawText(item->rect, item->action->text(), Qt::AlignHCenter | Qt::AlignVCenter);
        }

        x += d->gap + d->piesize.width();
        if (++gx == d->grid.width()){
            y += d->gap + d->piesize.height();
            x = d->gap;
            gx = 0;
        }
    }
}

void Toolbar::show()
{

}

void Toolbar::hide()
{

}
